(function() {
	var Util = Nokia.util,

		EMPTY_FN = function() {},

		LANDSCAPE_MODE = 'landscape',

		PORTRAIT_MODE = 'portrait',

		MINIVIEW_MODE = 'miniview';

	Nokia.ViewManager = new Nokia.Class({
		initialize: function(options) {
			var instance = this;

			instance.options = jQuery.extend({
				beforeRender: EMPTY_FN,
				render: EMPTY_FN,
				beforeShow: EMPTY_FN,
				show: EMPTY_FN
			}
			, options);

			instance.viewStack = [];
			instance.history = [];

			instance._currentHistoryIndex = instance._currentIndex = 0;
		},

		next: function() {
			var instance = this,
				index = instance.getCurrentIndex();

			instance.show(instance.viewStack[++index]);
		},

		prev: function() {
			var instance = this,
				index = instance.getCurrentIndex();

			instance.show(instance.viewStack[--index]);
		},

		back: function() {
			var instance = this;

			if (instance._currentHistoryIndex > 0) {
				var historyValue = instance.history[--instance._currentHistoryIndex];

				if (history) {
					instance._show.apply(instance, historyValue.args);
				}

			}

		},

		forward: function() {
			var instance = this;

			if (instance._currentHistoryIndex < instance.history.length - 1) {
				var history = instance.history[++instance._currentHistoryIndex];

				instance._show.apply(instance, history.args);
			}

		},

		clearHistory: function() {
			var instance = this;

			instance.history = [];
		},

		clear: function() {
			var instance = this;

			instance.viewStack = [];
		},

		show: function(view) {
			var instance = this;

			view = instance._getView(view);

			if (view) {
				var index = instance.getCurrentHistoryIndex();

				var historyValue = {
					view: view,
					args: arguments
				};

				instance.history.splice(index + 1, 0, historyValue);

				instance._currentHistoryIndex = jQuery.inArray(historyValue, instance.history);

				instance._show.apply(instance, arguments);

			}

		},

		_getView: function(view) {
			var instance = this;

			if (Util.isNumber(view)) {
				view = instance.viewStack[view];
			}

			if (view instanceof Nokia.View) {
				var index = jQuery.inArray(view, instance.viewStack);

				if (index > -1) {

					return view;

				}

			}

			return null;
		},

		_show: function() {
			var instance = this,
				view = instance._getView(arguments[0]);

			if (!view.isRendered()) {
				instance.options.beforeRender.apply(instance, [view]);
				view.render();
				instance.options.render.apply(instance, [view]);
			}

			instance.hideAll();

			instance.setCurrentIndex(jQuery.inArray(view, instance.viewStack));

			instance.options.show.apply(instance, [view]);

			view.show.apply(view, Array.prototype.slice.call(arguments, 1));
		},

		hide: function() {
			var instance = this,
				view = instance.getCurrentView();

			view.hide.apply(view, Array.prototype.slice.call(arguments, 1));
		},

		hideAll: function() {
			var instance = this;

			jQuery.each(instance.viewStack, function(i, view) {
				view.hide();
			});
		},

		getCurrentView: function() {
			var instance = this;

			return instance.viewStack[instance.getCurrentIndex()];
		},

		getCurrentHistoryIndex: function() {
			var instance = this;

			return instance._currentHistoryIndex;
		},

		getCurrentIndex: function() {
			var instance = this;

			return (instance._currentIndex || 0);
		},

		setCurrentIndex: function(index) {
			var instance = this;

			if (index <= instance.viewStack.length && index >= 0) {
				instance._currentIndex = index;
			}
		},

		add: function(view) {
			var instance = this;

			if (view instanceof Nokia.View) {
				instance.viewStack.push(view);
			}
		},

		remove: function(view) {
			var instance = this;

			if (Util.isNumber(view)) {
				Util.arrayRemove(instance.viewStack, view);
			}
			else if (view instanceof Nokia.View) {
				instance.viewStack.splice(jQuery.inArray(view, instance.viewStack), 1);
			}
		},

		getViews: function() {
			var instance = this;

			return instance.viewStack;
		},

		getHistorySize: function() {
			var instance = this;

			return instance.history.length;
		},

		size: function() {
			var instance = this;

			return instance.viewStack.length;
		},

		// Detect Orientation

		inLandscapeMode: function() {
			var instance = this;

			return instance.getViewMode() == LANDSCAPE_MODE;
		},

		inPortraitMode: function() {
			var instance = this;

			return instance.getViewMode() == PORTRAIT_MODE;
		},

		inMiniviewMode: function() {
			var instance = this;

			return instance.getViewMode() == MINIVIEW_MODE;
		},

		isNonTouch: function() {
			var instance = this;

			return (window.innerHeight * window.innerWidth) < 360*640;
		},

		getViewMode: function() {
			var instance = this,
				windowHeight = window.innerHeight;

			if (instance.isNonTouch()) {

				if (windowHeight > 240) {
					return PORTRAIT_MODE;
				} else {
					return LANDSCAPE_MODE;
				}

			} else {

				if (windowHeight <= 150) {
					return MINIVIEW_MODE;
				} else if (windowHeight > 150 && windowHeight <= 360) {
					return LANDSCAPE_MODE;
				} else {
					return PORTRAIT_MODE;
				}

			}

		}

	});
})();